package com.jinxin.platform.cdcardpassmgr.rpc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jinxin.platform.base.common.pojo.InvokeCfg;
import com.jinxin.platform.base.common.pojo.JsonResult;
import com.jinxin.platform.base.common.support.BusinessDelegate;
import com.jinxin.platform.cdcardpassmgr.bean.CdcardpassmgrDevice;
import com.jinxin.platform.cdcardpassmgr.bean.CdcardpassmgrPosition;
import com.jinxin.platform.cdcardpassmgr.bean.CdvehicleopersysOrgCorres;
import com.jinxin.platform.cdcardpassmgr.bean.bo.*;
import com.jinxin.platform.cdcardpassmgr.common.Constant;
import com.jinxin.platform.cdcardpassmgr.common.SysOrgInfo;
import com.jinxin.platform.cdcardpassmgr.common.SysUserVO;
import com.jinxin.platform.cdcardpassmgr.mapper.CdcardpassmgrDeviceMapper;
import com.jinxin.platform.cdcardpassmgr.mapper.CdvehicleopersysOrgCorresMapper;
import com.jinxin.platform.cdcardpassmgr.redis.RedisUtil;
import com.jinxin.platform.cdcardpassmgr.service.ICardpassmgrPositionService;
import com.jinxin.platform.cdcardpassmgr.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;

import static com.alibaba.fastjson.JSON.toJSONString;

/**
 * @description: (描述...)
 * @return:
 * @author: Linn
 * @time: 2020/05/18
 */
@Component
@Slf4j
public class CdcardpassmgrRpc {
    @Autowired
    private BusinessDelegate businessDelegate;
    @Autowired
    private CdcardpassmgrDeviceMapper deviceMapper;
    @Autowired
    private CdvehicleopersysOrgCorresMapper orgCorresMapper;
    @Value("${cdcardpassmgr.gpsnow-login.url}")
    private String loginUrl;
    @Value("${cdcardpassmgr.gpsnow-login.name}")
    private String loginName;
    @Value("${cdcardpassmgr.gpsnow-login.password}")
    private String loginPwd;
    @Value("${cdcardpassmgr.gpsnow-car.url}")
    private String carUrl;
    @Value("${cdcardpassmgr.position.url}")
    private String positionUrl;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ICardpassmgrPositionService positionService;


    /**
     * 通过父级ID查询组织
     * @return
     */
    public List<SysOrgInfo> listOrganizeByParentId(String orgPid) {
        InvokeCfg cfg = new InvokeCfg();
        cfg.setModuleKey(Constant.MODULE_KEY);
        cfg.setClassName(Constant.MODULE_CLASS_NAME);
        cfg.setFunName("listOrganizeByParentId");
        HashMap<String, Object> map = new HashMap<>();
        map.put("orgPid",orgPid);
        map.put("containsParent",false);
        cfg.setArgs(map);
        JsonResult result = businessDelegate.invoke(cfg);
        log.info("listCdcardpassmgrOrganizeByParentId =====>" + result.toString());
        if(result.getSuccess()){
            if (result.getData() == null) {
                return null;
            }
            return JSON.parseArray(toJSONString(result.getData()), SysOrgInfo.class);
        }
        return null;
    }

    /**
     * 获取我所在组织和我所管理的组织
     * @return
     */
    public List<SysOrgInfo> getManagedOrg() {
        InvokeCfg cfg = new InvokeCfg();
        cfg.setModuleKey(Constant.MODULE_KEY);
        cfg.setClassName(Constant.MODULE_CLASS_NAME);
        cfg.setFunName("getManagedOrg");
        HashMap<String, String> map = new HashMap<>();
        cfg.setArgs(map);
        JsonResult result = businessDelegate.invoke(cfg);
        log.info("getCdcardpassmgrManagedOrg =====>" + result.toString());
        if(result.getSuccess()){
            if (result.getData() == null) {
                return null;
            }
            return JSON.parseArray(toJSONString(result.getData()), SysOrgInfo.class);
        }
        return null;
    }

    public JsonResult listManagedUserList(){
        List<SysOrgInfo> managedOrgList = getManagedOrg();
        if(managedOrgList == null || managedOrgList.size() == 0){
            return JsonResult.error("获取我所在组织和我所管理的组织失败");
        }
        List<String> orgIdList = new ArrayList<>();
        managedOrgList.forEach(orgInfo->{
            orgIdList.add(orgInfo.getOrgId());
        });
        List<CdvehicleopersysOrgCorres> orgCorresList = orgCorresMapper.listByOrgIdList(orgIdList);
        List<String> userIdList = new ArrayList<>();
        orgCorresList.forEach(orgCorres->{
            userIdList.add(orgCorres.getThirdOrgId());
        });
        return JsonResult.ok(userIdList);
    }

    /**
     * 查询组织
     * @return
     */
    public JsonResult getOrgWithCondition() {
        InvokeCfg cfg = new InvokeCfg();
        cfg.setModuleKey(Constant.MODULE_KEY);
        cfg.setClassName(Constant.MODULE_CLASS_NAME);
        cfg.setFunName("getOrgWithCondition");
        HashMap<String, String> map = new HashMap<>();
        cfg.setArgs(map);
        JsonResult result = businessDelegate.invoke(cfg);
        log.info("getCdcardpassmgrOrgWithCondition =====>" + result.toString());
        if(result.getSuccess()){
            if (result.getData() == null) {
                return null;
            }
            List<SysOrgInfo> sysOrgInfos = JSON.parseArray(toJSONString(result.getData()), SysOrgInfo.class);
            return JsonResult.ok(sysOrgInfos);
        }
        return null;
    }
    /**
     * 获取当前用户对象
     *
     * @return SysUser
     */
    public SysUserVO getCurrentUser() {
        JsonResult result = getJsonResult(Constant.MODULE_KEY,"getCurrentUser");
        if (result.getSuccess()) {
            if (result.getData() == null) {
                return null;
            }
            log.info("getCdcardpassmgrCurrentUser:" + result.getData());
            return JSON.parseObject(toJSONString(result.getData()), SysUserVO.class);
        }
//        else {
//            SysUserVO userVO = new SysUserVO();
//            userVO.setUserId("1");
//            userVO.setUserAccount("admin");
//            userVO.setUserName("admin");
//            return userVO;
//        }
        return null;
    }

    public Object loginForGps() {
        Map<String,String> params = new HashMap<>();
        String loginName = new String(this.loginName.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
        params.put("name",loginName);
        params.put("password",this.loginPwd);
        try {
            HttpClientResult httpClientResult = HttpClientPoolUtil.doGet(this.loginUrl, params, true);
            if(Constant.REQUEST_STATUS_SUCCEED.equals(httpClientResult.getCode())){
                return httpClientResult.getContent();
            }
        } catch (Exception e) {
            log.error(e.toString());
        }
        return null;
    }

    public String[] getTokenAndUserId(){
        String[] result = new String[2];
        if(redisUtil.hasKey(Constant.REDIS_KEY_TOKEN) && redisUtil.hasKey(Constant.REDIS_KEY_USERID)){
            result[0] = (String) redisUtil.get(Constant.REDIS_KEY_TOKEN);
            result[1] = (String) redisUtil.get(Constant.REDIS_KEY_USERID);
            return result;
        }
        // application.properties文件是ISO-8859-1
        String loginName = new String(this.loginName.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
        Map<String,String> params = new HashMap<>();
//        params.put("name",this.loginName); // 本地用
        params.put("name",loginName);
        params.put("password",this.loginPwd);
        try {
            HttpClientResult httpClientResult = HttpClientPoolUtil.doGet(this.loginUrl, params, true);
            if(Constant.REQUEST_STATUS_SUCCEED.equals(httpClientResult.getCode())){
                DataResult response = JSON.parseObject(httpClientResult.getContent(), DataResult.class);
                JSONObject jsonObject = response.getData();
                if(jsonObject != null){
                    String token = jsonObject.getString("token");
                    String userId = jsonObject.getString("userId");
                    if(!StringUtils.isEmpty(token) && !StringUtils.isEmpty(userId)){
                        redisUtil.set(Constant.REDIS_KEY_TOKEN,token,36000L);//10分钟
                        redisUtil.set(Constant.REDIS_KEY_USERID,userId,36000L);//10分钟
                        result[0] = token;
                        result[1] = userId;
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.toString());
        }
        return result;
    }

    public Object doRequest(String type,String url,String jsonStr){
        if(StringUtils.isEmpty(url)){
            return null;
        }
        Map<String,String> params = new HashMap<>();
        if(!StringUtils.isEmpty(jsonStr)){
            params = StringUtil.jsonToMap(URLEncoder.decodeURIComponent(jsonStr));
        }
        Map<String,String> headers = new HashMap<>();
        headers.put("token", getTokenAndUserId()[0]);
        switch (type){
            case "get":
                try {
                    HttpClientResult clientResult = HttpClientPoolUtil.doGet(url, headers,params, true);
                    if(Constant.REQUEST_STATUS_SUCCEED.equals(clientResult.getCode())){
                        return clientResult.getContent();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            case "post":
                try {
                    HttpClientResult clientResult = HttpClientPoolUtil.doPost(url, headers,params, true);
                    if(Constant.REQUEST_STATUS_SUCCEED.equals(clientResult.getCode())){
                        return clientResult.getContent();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            default:
                return null;
        }

    }

    public JsonResult getStaOverview() {
        List<CdcardpassmgrPosition> positionInfos = new ArrayList<>();
        try {
            Map<String,String> headers = new HashMap<>();
            headers.put("token", getTokenAndUserId()[0]);
            String userId = getTokenAndUserId()[1];
            Map<String,String> params = new HashMap<>();
            params.put("userId",userId);
            int year = DateUtil.getCurrentField(Calendar.YEAR);
            int month = DateUtil.getCurrentField(Calendar.MONTH);
            for (int i = 1; i <= month; i++) {
                String[] timeArr = DateUtil.getFirstLastDayOfMonth(year, i);
//                String key = Constant.REDIS_KEY_START_TIME;
//                String startTime = redisUtil.hasKey(key) ? (String)redisUtil.get(key) : DateUtil.getFirstDayOfCurrentMonth();
                params.put("startTime",timeArr[0]);
                String endTime = i == month ? DateUtil.getCurrentDayYMDHHs() : timeArr[1];
                params.put("endTime",endTime);
                params.put("rowCount",Integer.MAX_VALUE+"");
                params.put("pageNO:","1");
    //            Map<Long,PositionInfo> positionInfoMap = new HashMap<>();
                HttpClientResult clientResult = HttpClientPoolUtil.doPost(this.positionUrl, headers,params, true);
                if(Constant.REQUEST_STATUS_SUCCEED.equals(clientResult.getCode())){
                    DataResult2 result = JSON.parseObject(clientResult.getContent(), DataResult2.class);
                    if(result != null){
                        JSONArray data = result.getData();
                        for (int j = 0; j < data.size(); j++) {
                            JSONObject jsonObj = data.getJSONObject(j);
                            CdcardpassmgrPosition positionInfo = JSON.parseObject(jsonObj.toJSONString(), CdcardpassmgrPosition.class);
                            if(positionInfo != null){
                                positionInfos.add(positionInfo);
                                //positionInfoMap.put(positionInfo.getCarId(),positionInfo);
                            }
                        }
                    }
                }
            }
            if(positionInfos.size() > 0){
                positionInfos.forEach(item->{
                    positionService.saveOrUpdate(item);
                });
            }
//            if(!positionInfoMap.isEmpty()){
//                List<CdcardpassmgrPosition> list = positionMapper.list(new HashMap());
//                list.forEach(item->{
//                    positionInfoMap.remove(item.getCarId());
//                });
//                positionInfoMap.forEach((aLong, positionInfo) -> {
//                    positionInfos.add(positionInfo);
//                });
//            }
        } catch (Exception e) {
            log.error(e.toString());
        }
        return JsonResult.ok(positionInfos);
    }

    public JsonResult selectDeviceList() {
        Map<String,String> params = new HashMap<>();
        params.put("name",this.loginName);
        params.put("password",this.loginPwd);
        List<DeviceInfo> deviceList = new ArrayList<>();
        try {
            HttpClientResult httpClientResult = HttpClientPoolUtil.doGet(this.loginUrl, params, true);
            if(Constant.REQUEST_STATUS_SUCCEED.equals(httpClientResult.getCode())){
                DataResult response = JSON.parseObject(httpClientResult.getContent(), DataResult.class);
                JSONObject jsonObject = response.getData();
                if(jsonObject != null){
                    String token = jsonObject.getString("token");
                    Map<String,String> headers = new HashMap<>();
                    headers.put("token",token);
                    Map<String,String> params2 = new HashMap<>();
                    params2.put("pagIndex","1");
                    params2.put("pageSize","100");
                    HttpClientResult clientResult = HttpClientPoolUtil.doGet(this.carUrl, headers, params2, true);
                    if(Constant.REQUEST_STATUS_SUCCEED.equals(clientResult.getCode())){
                        DataResult2 result = JSON.parseObject(clientResult.getContent(), DataResult2.class);
//                        {
//                            "activeTime":"2021-08-15 11:48:14",
//                                "carGroupId":0,
//                                "carId":195300,
//                                "carNO":"渝A12345",
//                                "carStatus":Object{...},
//                            "carType":8,
//                                "imei":"863013050444051",
//                                "joinTime":"2021-07-15 17:06:53",
//                                "machineName":"渝BT5027",
//                                "machineType":85,
//                                "platformTime":"2022-08-15",
//                                "remark":"",
//                                "saleTime":"2021-08-08 16:19:26",
//                                "serviceState":0,
//                                "serviceTime":"2022-08-15",
//                                "simNO":"898604351918C1262471",
//                                "updateTime":"2021-09-22 16:09:15",
//                                "userId":7198
//                        }
                        if(result != null){
                            JSONArray data = result.getData();
                            for (int i = 0; i < data.size(); i++) {
                                JSONObject jsonObj = data.getJSONObject(i);
                                DeviceInfo deviceInfo = new DeviceInfo();
                                deviceInfo.setId(jsonObj.getString("imei"));
                                deviceInfo.setNickName(jsonObj.getString("machineName"));
                                deviceList.add(deviceInfo);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.toString());
        }
        return JsonResult.ok(deviceList);
    }

    /**
     * 字典类型获取字典项
     * @param dictType 字典类型
     * @return
     */
    public JsonResult getDictItems(String dictType) {
        InvokeCfg cfg = new InvokeCfg();
        cfg.setModuleKey(Constant.MODULE_KEY);
        cfg.setClassName(Constant.MODULE_CLASS_NAME);
        cfg.setFunName("getDictItems");
        HashMap<String, String> map = new HashMap<>();
        map.put("dictType", dictType);
        cfg.setArgs(map);
        JsonResult result = businessDelegate.invoke(cfg);
        log.info("getDictItems =====>" + result.toString());
        if(result.getSuccess()){
            return result;
        }
//        else {
//            List<DictItem> list = new ArrayList<>();
//            DictItem item1 = new DictItem("1","工程车辆");
//            DictItem item2 = new DictItem("2","社会车辆");
//            list.add(item1);
//            list.add(item2);
//            return JsonResult.ok(list);
//        }
        return null;
    }

    private JsonResult getJsonResult(String keyName,String funName) {
        InvokeCfg cfg = new InvokeCfg();
        cfg.setModuleKey(keyName);
        cfg.setClassName(Constant.MODULE_CLASS_NAME);
        cfg.setFunName(funName);
        return businessDelegate.invoke(cfg);
    }

    public JsonResult syncDeviceData() {
        InvokeCfg cfg = new InvokeCfg();
        cfg.setModuleKey(Constant.MODULE_KEY);
        cfg.setClassName(Constant.MODULE_CLASS_NAME);
        cfg.setFunName("syncDeviceData");
        Map<String, String> argsMap = new HashMap<>();
        argsMap.put("moduleCode",Constant.MODULE_KEY);
        cfg.setArgs(argsMap);
        JsonResult result = businessDelegate.invoke(cfg);
        log.info("通行管理模块同步设备，返回数据: " + result.toString());
        if (result.getSuccess()) {
            List<CdcardpassmgrDevice> deviceList =
                    JSON.parseArray(result.getData().toString(),CdcardpassmgrDevice.class);
            int count = 0;
            for (CdcardpassmgrDevice device: deviceList){
                CdcardpassmgrDevice device1 = deviceMapper.selectByKey(device.getId());
                if(StringUtils.isEmpty(device.getNickName())){
                    device.setNickName(device.getDeviceName());
                }
                if(device1 == null){
                    device.setCreateTime(LocalDateTime.now());
                    deviceMapper.insert(device);
                    count++;
                }else {
                    BeanUtils.copyProperties(device,device1);
                    deviceMapper.updateByKey(device1);
                }
            }
            return JsonResult.ok("成功同步"+count+"条记录","");
        }else {
            return JsonResult.error("同步失败");
        }
    }

    /**
     *
     * @param serialNum 设备序列号不是BCCA同步过来的设备mac
     * @param password 通讯密码默认是FFFFFFFF
     * @param recordCode 记录代码01读卡记录
     * @param recordIndex 记录序号
     * @param readCount  读取数据量
     * @param mac  设备mac
     * @return
     */
    public JsonResult readTheRecord(String serialNum,String password,String recordCode,Integer recordIndex,Integer readCount, String mac) {
        if(StringUtils.isEmpty(serialNum)){
            return JsonResult.error("设备序列号不存在");
        }
        if(StringUtils.isEmpty(password)){
            return JsonResult.error("通讯密码不存在");
        }
        if(StringUtils.isEmpty(recordCode)){
            return JsonResult.error("记录代码不存在");
        }
        if(StringUtils.isEmpty(recordIndex)){
            return JsonResult.error("记录序号不存在");
        }
        if(StringUtils.isEmpty(readCount)){
            return JsonResult.error("读取数据量不存在");
        }
        JSONObject pJsonObj = new JSONObject();
        pJsonObj.put("p1", NumConvertUtil.strToHexString(serialNum));
        pJsonObj.put("p2",password);
        pJsonObj.put("p3", recordCode);// 1字节2位，不用处理了
        pJsonObj.put("p4", NumConvertUtil.intToHexString(recordIndex,8));// 4字节8位
        pJsonObj.put("p5", NumConvertUtil.intToHexString(readCount,8));// 4字节8位
        JsonResult result = controlDevice("Read the record",mac, pJsonObj.toJSONString());
        log.info("通行管理模块控制读取记录返回："+result.toString());
        if (result.getSuccess()) {
            return JsonResult.ok("读取记录成功",result.getData());
        }else {
            return JsonResult.error("设备控制错误,读取记录失败");
        }
    }

    /**
     * 读取记录指针信息
     * @param serialNum 设备序列号不是BCCA同步过来的设备mac
     * @param password 通讯密码默认是FFFFFFFF
     * @param mac  设备mac
     * @return
     */
    public JsonResult readThePointRecord(String serialNum,String password,String mac) {
        if(StringUtils.isEmpty(serialNum)){
            return JsonResult.error("设备序列号不存在");
        }
        if(StringUtils.isEmpty(password)){
            return JsonResult.error("通讯密码不存在");
        }
        JSONObject pJsonObj = new JSONObject();
        pJsonObj.put("p1",NumConvertUtil.strToHexString(serialNum));
        pJsonObj.put("p2",password);
        JsonResult result = controlDevice("Read the pointer record",mac, pJsonObj.toJSONString());
        log.info("通行管理模块控制(读取记录指针信息)返回："+result.toString());
        if (result.getSuccess()) {
            return JsonResult.ok("读取记录指针信息成功",result.getData());
        }else {
            return JsonResult.error("设备控制错误,读取记录指针信息失败");
        }
    }

    private JsonResult controlDevice(String operation, String mac,String controlParams) {
        InvokeCfg cfg = new InvokeCfg();
        cfg.setModuleKey(Constant.MODULE_KEY);
        cfg.setClassName(Constant.MODULE_CLASS_NAME);
        cfg.setFunName("controlDevice");
        Map<String, Object> map = new HashMap<>();
        map.put("operation", operation);
        map.put("serialNum", mac);
        map.put("controlParams", controlParams);
        cfg.setArgs(map);
        log.info("通行管理模块控制设备的参数: " + map.toString());
        return businessDelegate.invoke(cfg);
    }


}
